<template>
  <div>
    <h1>计算属性和监听</h1>
    <input type="text" v-model="user.firstName" /><br />
    <input type="text" v-model="user.lastName" /><br />
    <input type="text" v-model="user.child.lastName" /><br />
    <input type="text" v-model="fullName1" /><br />
    <input type="text" v-model="fullName2" /><br />
    <input type="text" v-model="fullName3" /><br />
    <input type="text" v-model="fullName4" />
  </div>
</template>

<script lang="ts">
import {
  computed,
  defineComponent,
  reactive,
  ref,
  watch,
  watchEffect,
} from "vue";

export default defineComponent({
  setup() {
    // vue3当中计算属性的用法  get  set
    const user = reactive({
      firstName: "zheshu",
      lastName: "li",
      child: {
        firstName: "xiaozheshu",
        lastName: "xiaoli",
      },
    });
    // 需求：根据firstName和lastName的值得到全名 fullName
    // 就算属性的get方法
    const fullName1 = computed(() => {
      return user.firstName + "-" + user.lastName;
    });
    console.log(fullName1);
    //set
    // 当计算属性得到的值发生变化，就会触发set函数，参数更新过后的
    const fullName2 = computed({
      get() {
        return user.firstName + "-" + user.lastName;
      },
      set(value: string) {
        // Object is of type 'unknown'.
        console.log(value);
        const arr = value.split("-");
        // 字符串通过split分割后得到的值是数组
        user.firstName = arr[0];
        user.lastName = arr[1];
      },
    });

    // watch
    const fullName3 = ref("");
    /* watch(
      user,
      () => {
        fullName3.value = user.firstName + "-" + user.child.lastName;
      },
      {
        deep: true, //深度监视
        immediate: true, //立即触发
      }
    );
    watch(fullName3, (newValue: string, oldValue) => {
      console.log(newValue);
      console.log(oldValue);
      let arr = newValue.split("-");
      user.firstName = arr[0];
      user.child.lastName = arr[1];
    }); */

    // watch一次监听一个数据，可以写多次
    // 还有一种语法 一个watch可以监听多个数据，当是基本数据类型时，直接写，当是引用数据类型，就需要使用函数的方式
    // 当watch监听多个时，当其中任何一个发生变化，都会触发watch的回调函数
    watch(
      [fullName3, () => user.firstName, () => user.lastName],
      (values, oldVaules) => {
        console.log(values);
        console.log(oldVaules);
        // 分情况而定写多种逻辑
        // 并列的要不执行if 要不执行else if
        // 当firstName或者lastName发生改变时，获取fullName3
        if (values[1] != oldVaules[1] || values[2] != oldVaules[2]) {
          fullName3.value = values[1] + "-" + values[2];
        } else if (values[0] != oldVaules[1]) {
          let arr = values[0].split("-");
          user.firstName = arr[0];
          user.lastName = arr[1];
        }

        // 不是并列  这两个if条件是没有关系，只有符合其中if中的条件，他们的内部逻辑就会发生----后果 造成死循环
        // 如果fullName3发生变化，获新的firstName和lastName， 监听的也有firstName和lastName
        /*  if (values[0] != oldVaules[1]) {
          let arr = values[0].split("-");
          user.firstName = arr[0];
          user.lastName = arr[1];
        } */
        // 当fullName3变化 更新firstName lastName 
      }
    );

    // watchEffect   立即执行监听
    const fullName4 = ref("");
    watchEffect(() => {
      fullName4.value = user.firstName + "-" + user.lastName;
    });
    // vue2中的ref 获取DOM元素       vue3中的ref 指ref对象
    return {
      user,
      fullName1,
      fullName2,
      fullName3,
      fullName4,
    };
  },
});
</script>

<style scoped>

</style>